package com.beardedhen.harmonybootstrap;

import com.beardedhen.harmonybootstrap.api.attributes.BootstrapBrand;
import com.beardedhen.harmonybootstrap.api.defaults.DefaultBootstrapBrand;
import com.beardedhen.harmonybootstrap.api.defaults.DefaultBootstrapSize;
import com.beardedhen.harmonybootstrap.api.view.BootstrapBrandView;
import com.beardedhen.harmonybootstrap.api.view.BootstrapSizeView;
import com.beardedhen.harmonybootstrap.api.view.RoundableView;
import com.beardedhen.harmonybootstrap.utils.DimenUtils;
import com.beardedhen.harmonybootstrap.utils.UiUtil;
import com.beardedhen.harmonybootstrap.utils.ViewUtils;

import ohos.agp.components.AttrSet;
import ohos.agp.components.TextField;
import ohos.agp.components.element.Element;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

/**
 * BootstrapEditText allows users to enter values like a regular openharmony TextField, and allows coloring
 * via BootstrapBrand, and rounding of its background.
 */
public class BootstrapEditText extends TextField implements BootstrapBrandView, RoundableView, BootstrapSizeView {

    private static final String BOOTSTRAP_EDITTEXT_BOOTSTRAP_SIZE = "bootstrapSize";
    private static final String BOOTSTRAP_EDITTEXT_ROUNDED_CORNERS = "roundedCorners";
    private static final String BOOTSTRAP_EDITTEXT_BOOTSTRAP_BRAND = "bootstrapBrand";

    private float baselineFontSize;
    private float baselineVertPadding;
    private float baselineHoriPadding;
    private float baselineStrokeWidth;
    private float baselineCornerRadius;

    private BootstrapBrand bootstrapBrand;
    private float bootstrapSize;
    private boolean rounded;

    public BootstrapEditText(Context context) throws NotExistException, WrongTypeException, IOException {
        super(context);
        initialise(null);
    }

    public BootstrapEditText(Context context, AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {
        super(context, attrSet);
        initialise(attrSet);
    }

    public BootstrapEditText(Context context, AttrSet attrSet, String styleName) throws NotExistException, WrongTypeException, IOException {
        super(context, attrSet, styleName);
        initialise(attrSet);
    }

    private void initialise(AttrSet attrSet) throws NotExistException, WrongTypeException, IOException {
        if (attrSet == null) {
            return;
        }
        try {
            setIsRounded(attrSet.getAttr(BOOTSTRAP_EDITTEXT_ROUNDED_CORNERS).isPresent() ? attrSet.getAttr(
                BOOTSTRAP_EDITTEXT_ROUNDED_CORNERS).get().getBoolValue() : false);

            int typeOrdinal = -1;
            if (attrSet.getAttr(BOOTSTRAP_EDITTEXT_BOOTSTRAP_BRAND).isPresent()) {
                String typeOrdinalStr = attrSet.getAttr(BOOTSTRAP_EDITTEXT_BOOTSTRAP_BRAND).get().getStringValue().trim();
                typeOrdinal = UiUtil.getBootstrapBrandInt(typeOrdinalStr);
            }

            int sizeOrdinal = -1;
            if (attrSet.getAttr(BOOTSTRAP_EDITTEXT_BOOTSTRAP_SIZE).isPresent()) {
                String sizeOrdinalStr = attrSet.getAttr(BOOTSTRAP_EDITTEXT_BOOTSTRAP_SIZE).get().getStringValue().trim();
                sizeOrdinal = UiUtil.getBootstrapSizeInt(sizeOrdinalStr);
            }

            this.bootstrapBrand = DefaultBootstrapBrand.fromAttributeValue(typeOrdinal);
            this.bootstrapSize = DefaultBootstrapSize.fromAttributeValue(sizeOrdinal).scaleFactor();
        } catch(Exception e) {
            e.printStackTrace();
        }

        baselineFontSize = DimenUtils.pixelsFromSpResource(getContext(), ResourceTable.Float_bootstrap_button_default_font_size);
        baselineVertPadding = DimenUtils.pixelsFromDpResource(getContext(),ResourceTable.Float_bootstrap_edit_text_vert_padding);
        baselineHoriPadding = DimenUtils.pixelsFromDpResource(getContext(),ResourceTable.Float_bootstrap_edit_text_hori_padding);
        baselineStrokeWidth = DimenUtils.pixelsFromDpResource(getContext(),ResourceTable.Float_bootstrap_edit_text_edge_width);
        baselineCornerRadius = DimenUtils.pixelsFromDpResource(getContext(),ResourceTable.Float_bootstrap_edit_text_corner_radius);

        updateBootstrapState();
        invalidate();
    }

    @Override
    public void setBootstrapBrand(BootstrapBrand bootstrapBrand) {
        this.bootstrapBrand = bootstrapBrand;
        updateBootstrapState();
    }

    @Override
    public BootstrapBrand getBootstrapBrand() {
        return bootstrapBrand;
    }

    @Override
    public void setRounded(boolean rounded) {
        this.rounded = rounded;
        updateBootstrapState();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        if (!enabled) {
            this.clearFocus();
            this.setTextColor(Color.GRAY);
        } else {
            this.setTextColor(Color.BLACK);
        }
    }

    @Override
    public boolean isRounded() {
        return rounded;
    }

    @Override
    public float getBootstrapSize() {
        return bootstrapSize;
    }

    @Override
    public void setBootstrapSize(float bootstrapSize) {
        this.bootstrapSize = bootstrapSize;
        updateBootstrapState();
    }

    @Override
    public void setBootstrapSize(DefaultBootstrapSize bootstrapSize) {
        setBootstrapSize(bootstrapSize.scaleFactor());
    }

    private void setIsRounded(boolean rounded) {
        this.rounded = rounded;
        postLayout();
    }

    private void updateBootstrapState() {
        int vPadding = (int) (baselineVertPadding * bootstrapSize);
        int hPadding = (int) (baselineHoriPadding * bootstrapSize);
        setPadding(vPadding, hPadding, vPadding, hPadding);

        int strokeWidth = (int) (baselineStrokeWidth * bootstrapSize);
        float cornerRadius = baselineCornerRadius * bootstrapSize;

        final float fontSize = baselineFontSize * bootstrapSize;
        setTextSize((int) fontSize);

        Element bg = BootstrapDrawableFactory.bootstrapEditText(
                getContext(),
                bootstrapBrand,
                strokeWidth,
                cornerRadius,
                rounded);
        ViewUtils.setBackgroundDrawable(this,bg);
    }
}
